home *** CD-ROM | disk | FTP | other *** search
- From: boysko@l.UUCP (Glenn Boysko)
- Newsgroups: comp.sources.misc
- Subject: v02i079: sun2ps - sun rasterfile to PostScript image translator
- Message-ID: <8803272342.AA04240@mandrill.CES.CWRU.Edu>
- Date: 27 Mar 88 22:42:28 GMT
- Approved: allbery@ncoast.UUCP
-
- comp.sources.misc: Volume 2, Issue 79
- Submitted-By: "Glenn Boysko" <boysko@l.UUCP>
- Archive-Name: sun2ps/part01
-
- Enclosed is "sun2ps" - a Sun Rasterfile to PostScript image translator
- that uses run length encoding.
-
- Glenn Boysko
- mandrill!boysko
- boysko@mandrill.ces.cwru.edu
-
- ---------------------------------- cut here -----------------------------------
- #!/bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #!/bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # Makefile
- # sun2ps.c
- # sun2ps.l
- # This archive created: Fri Mar 25 16:20:42 1988
- # By: Glenn J. Boysko(Case Western Reserve University)
- #
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'Makefile'" '(515 characters)'
- if test -f 'Makefile'
- then
- echo shar: over-writing existing file "'Makefile'"
- fi
- sed 's/^X//' << \SHAR_EOF > 'Makefile'
- X#
- X# Makefile for Sun2ps and other utilities...
- X#
- X# Glenn Boysko {decvax, sun}!mandrill!boysko
- X# boysko@mandrill.cwru.edu
- X
- X# Diagnostics about the amount of compression, avg run length, etc
- X# are not reported, by default. To view these diagnostics on stderr,
- X# define the flag DIAGS. Extra diagnostics about the specifics of
- X# raster file (num of samples, image depth, etc) can be found by
- X# defining EXTRADIAGS.
- XDIAGFLAGS = -DDIAGS -DEXTRADIAGS
- X
- XCFLAGS = -O $(DIAGFLAGS)
- X
- Xsun2ps: sun2ps.o
- X cc -o sun2ps sun2ps.o
- SHAR_EOF
- if test 515 -ne "`wc -c 'Makefile'`"
- then
- echo shar: error transmitting "'Makefile'" '(should have been 515 characters)'
- fi
- echo shar: extracting "'sun2ps.c'" '(12873 characters)'
- if test -f 'sun2ps.c'
- then
- echo shar: over-writing existing file "'sun2ps.c'"
- fi
- sed 's/^X//' << \SHAR_EOF > 'sun2ps.c'
- X/******************************************************************************
- X* *
- X* File: sun2ps.c *
- X* Author: Glenn Boysko *
- X* Organization: Case Western Reserve University *
- X* EMail: {decvax, sun}!mandrill!boysko *
- X* boysko@mandrill.cwru.edu *
- X* Created: Wed Mar 23 9:25pm *
- X* Contents: Sun Rasterfile to PostScript image (using a run-length *
- X* encoding scheme.) *
- X* *
- X* (Adapted from "postimage" filter by J. R. Bammi.) *
- X* *
- X* @(#)sun2ps.c 1.7
- X******************************************************************************/
- X
- X/*
- X * Usage:
- X * sun2ps [-s sizex sizey] [-t transx transy] [-r rot] [-l] [-i] [-a] file ...
- X *
- X * -s sizex sizey = size of postscript image - default 7.5 x 10 inches.
- X * -t transx transy = translate image - default 0.5 0.5 inches
- X * -r rotate = rotate image - default 0 degress
- X * -l = landscape (overrides *all* settings.)
- X * -i = inverse image - default no inverse
- X * (Inverse enabled implies white on black.)
- X * -a = maintain correct aspect ratio - default none.
- X *
- X */
- X
- X/* Sun standard raster file format (as obtained by screendump(1)).
- X *
- X * Header (8 16-bit quantities)
- X * Color Map
- X * Image
- X *
- X */
- X
- X/* Header Format:
- X *
- X * ras_magic (int) Raster Magic number 0x59a66a95
- X * ras_width (int) Width of image in pixels.
- X * ras_height (int) Height of image in pixels.
- X * ras_depth (int) Bits per pixel. Either 1 or 8 bits.
- X * ras_length (int) Length of image in bytes.
- X * ras_type (int) Type of file. Assumed to be RT_STANDARD (1) if
- X * produced by a screendump command.
- X * ras_maptype (int) Type of color map.
- X * ras_maplength (int) Length of color map in bytes.
- X *
- X */
- X
- X/* Ras_maplength bytes of Color map data. */
- X
- X/* Ras_length bytes of Image data. */
- X
- X#include <stdio.h>
- X#include <rasterfile.h>
- X
- X/* Buffer and Input Modes... */
- X#define LITERAL 0
- X#define COPY 1
- X#define IGNORE 2
- X
- X/* Transmission Variables. */
- Xint BufCount;
- X
- Xunsigned char Buffer[128],
- X CurrByte,
- X NextByte,
- X *BufferP = Buffer;
- X
- X/* Diagnostic Variables. */
- Xint DiagNLongRuns = 0,
- X DiagMaxRunLength = 0,
- X DiagNumRuns = 0;
- Xdouble DiagSumRunLength = 0;
- X
- Xmain(argc,argv)
- Xint argc;
- Xchar **argv;
- X{
- X FILE *fp, *fopen();
- X int land, inv, aspect;
- X char *filename;
- X double sizex, sizey, transx, transy, rotate;
- X
- X extern double atof();
- X
- X fp = stdin;
- X aspect = 0;
- X land = 0;
- X filename = "STDIN";
- X sizex = 7.5;
- X sizey = 10.0;
- X transx = transy = 0.5;
- X rotate = 0.0;
- X
- X while(--argc > 0)
- X {
- X ++argv;
- X if((*argv)[0] == '-')
- X {
- X switch((*argv)[1])
- X {
- X case 'l':
- X case 'L':
- X land = 1;
- X break;
- X
- X case 's':
- X case 'S':
- X sizex = atof(*++argv);
- X sizey = atof(*++argv);
- X argc -= 2;
- X break;
- X
- X case 't':
- X case 'T':
- X transx = atof(*++argv);
- X transy = atof(*++argv);
- X argc -= 2;
- X break;
- X
- X case 'r':
- X case 'R':
- X rotate = atof(*++argv);
- X argc--;
- X break;
- X
- X case 'I':
- X case 'i':
- X inv = 1;
- X break;
- X
- X case 'A':
- X case 'a':
- X aspect = 1;
- X break;
- X
- X default:
- X fprintf(stderr,"Illegal switch %c - ignored\n",
- X (*argv)[1]);
- X }
- X }
- X else
- X {
- X if((fp = fopen(*argv, "r")) == (FILE *)NULL)
- X {
- X fprintf(stderr,"Cannot open %s\n",*argv);
- X exit(1);
- X }
- X filename = *argv;
- X }
- X }
- X if (land)
- X {
- X transx = 8.0;
- X transy = 0.5;
- X sizex = 10.0;
- X sizey = 7.5;
- X rotate = 90.0;
- X }
- X process(fp, aspect, inv, filename, sizex, sizey, transx, transy, rotate);
- X}
- X
- Xprocess(Fp, aspect, inv, filename, sizex, sizey, transx, transy, rotate)
- XFILE *Fp;
- Xint inv, aspect;
- Xdouble sizex, sizey, transx, transy, rotate;
- Xchar *filename;
- X{
- X struct rasterfile rh;
- X int i, BS;
- X
- X if (fread((char *) (&rh), sizeof(rh), 1, Fp) != 1)
- X {
- X Error("Can't read rasterfile header\n");
- X }
- X
- X#ifdef EXTRADIAGS
- X fprintf(stderr, "Ras_width = %d, Ras_height = %d, Ras_depth = %d\n",
- X rh.ras_width, rh.ras_height, rh.ras_depth);
- X fprintf(stderr, "Ras_length = %d, Ras_type = %d, Ras_maplength = %d\n",
- X rh.ras_length, rh.ras_type, rh.ras_maplength);
- X#endif
- X
- X if (rh.ras_magic != RAS_MAGIC)
- X {
- X Error("Input file is not a Sun Rasterfile!\n");
- X }
- X
- X if (rh.ras_type != RT_STANDARD)
- X {
- X Error("Input file is not in Sun Standard Rasterfile format.\n");
- X }
- X
- X /* Scan off color table */
- X for (i=0; i < rh.ras_maplength; i++)
- X {
- X gb(Fp);
- X }
- X
- X if (aspect)
- X {
- X if ((sizex / rh.ras_width) < (sizey / rh.ras_height))
- X {
- X sizey = sizex * (rh.ras_height * 1.0 / rh.ras_width);
- X }
- X else
- X {
- X sizex = sizey * (rh.ras_width * 1.0 / rh.ras_height);
- X }
- X
- X }
- X
- X PrintPostScriptRoutines(rh.ras_height, rh.ras_width, rh.ras_depth,
- X transx, transy, sizex, sizey, rotate);
- X
- X BS = Encode(Fp, rh.ras_length, inv);
- X
- X#ifdef DIAGS
- X fprintf(stderr, "Encoded %d bytes into %d. (Ratio=%d%%)\n",
- X rh.ras_length, BS, 100 - (100 * BS) / rh.ras_length);
- X Diags();
- X#endif
- X fclose(Fp);
- X
- X PrintPostScriptClosing();
- X}
- X
- X/******************************************************************************
- X* I/O Routines. *
- X******************************************************************************/
- Xint
- Xgb(Fp) /* Get a byte from Fp. */
- XFILE *Fp;
- X{
- X int byte;
- X
- X if (!feof(Fp))
- X byte = getc(Fp);
- X else
- X Error("Premature EOF.\n");
- X if (ferror(Fp))
- X Error("I/O Error.\n");
- X return(byte);
- X}
- X
- Xint
- Xgw(Fp) /* Get a word (int) from Fp. */
- XFILE *Fp;
- X{
- X int word;
- X
- X if (!feof(Fp))
- X word = getw(Fp);
- X else
- X Error("Premature EOF.\n");
- X if (ferror(Fp))
- X Error("I/O Error.\n");
- X return(word);
- X}
- X
- XSendHex(Byte) /* Send a Hex char to Stdout. */
- Xunsigned char Byte;
- X{
- X static int LineCount = 0;
- X
- X printf("%02x", 0xff & Byte);
- X if (++LineCount == 16)
- X {
- X putchar('\n');
- X LineCount = 0;
- X }
- X}
- X
- Xint
- XSendBuffer(Inv) /* Send a buffer to Stdout. Return BytesSent. */
- Xint Inv;
- X{
- X int i, BytesSent;
- X
- X if (BufferMode() == LITERAL)
- X {
- X SendHex( (unsigned char) 0xff & BufCount );
- X for (i = 0; i < BufCount+1; i++)
- X {
- X SendHex( (Inv) ? Buffer[i] : ~Buffer[i]);
- X }
- X BytesSent = BufCount+2;
- X }
- X else if (BufferMode() == COPY)
- X {
- X SendHex( (unsigned char) 0xff & (0x100 + BufCount) );
- X SendHex( (Inv) ? Buffer[0] : ~Buffer[0]);
- X BytesSent = 2;
- X DiagRecLRun(mag(BufCount)+1);
- X }
- X return(BytesSent);
- X}
- X
- X/******************************************************************************
- X* Utility Routines. *
- X******************************************************************************/
- Xint
- Xmag(Byte) /* Magitude of a signed char. */
- Xint Byte;
- X{
- X if (Byte & 0x80)
- X {
- X /* Signed */
- X Byte = ~(--Byte);
- X }
- X return( 0xff & Byte );
- X}
- X
- X/******************************************************************************
- X* Buffer Management Routines. *
- X******************************************************************************/
- Xint
- XInputMode()
- X{
- X if (CurrByte == NextByte)
- X return(COPY);
- X return(LITERAL);
- X}
- X
- Xint
- XBufferMode()
- X{
- X if (BufCount >= 0 && BufCount <= 127)
- X return(LITERAL);
- X else if (BufCount >= -127 && BufCount <= -1)
- X return(COPY);
- X return(IGNORE);
- X}
- X
- XInitLitMode(Fp, NBytes, Inv)
- XFILE *Fp;
- Xint *NBytes, Inv;
- X{
- X BufferP = Buffer;
- X BufCount = -1;
- X ContLitMode(Fp, NBytes, Inv);
- X}
- X
- XContLitMode(Fp, NBytes, Inv)
- XFILE *Fp;
- Xint *NBytes, Inv;
- X{
- X if (BufCount == 127)
- X {
- X SendBuffer(Inv);
- X BufferP = Buffer;
- X BufCount = -1;
- X }
- X *BufferP++ = CurrByte;
- X BufCount++;
- X CurrByte = NextByte;
- X NextByte = (unsigned char) gb(Fp);
- X (*NBytes)--;
- X}
- X
- XInitCopyMode(Fp, NBytes, Inv)
- XFILE *Fp;
- Xint *NBytes, Inv;
- X{
- X BufferP = Buffer;
- X *BufferP++ = CurrByte;
- X BufCount = -1;
- X CurrByte = (unsigned char) gb(Fp);
- X NextByte = (unsigned char) gb(Fp);
- X *NBytes -= 2;
- X}
- X
- XContCopyMode(Fp, NBytes, Inv)
- XFILE *Fp;
- Xint *NBytes, Inv;
- X{
- X if (BufCount == -127)
- X {
- X SendBuffer(Inv);
- X InitCopyMode(Fp, NBytes, Inv);
- X DiagNLongRuns++;
- X }
- X BufCount--;
- X CurrByte = NextByte;
- X NextByte = gb(Fp);
- X (*NBytes)--;
- X}
- X
- X/******************************************************************************
- X* Encoding Algorithm. *
- X******************************************************************************/
- Xint
- XEncode(Fp, NBytes, Inv)
- XFILE *Fp;
- Xint NBytes, Inv;
- X{
- X int BytesSent = 0;
- X
- X /* Initialize Buffer, BufCount, NextByte, CurrByte */
- X CurrByte = (unsigned char) gb(Fp);
- X NextByte = (unsigned char) gb(Fp);
- X if (InputMode() == LITERAL)
- X {
- X InitLitMode(Fp, &NBytes, Inv);
- X }
- X else
- X {
- X InitCopyMode(Fp, &NBytes, Inv);
- X }
- X while (NBytes > 2)
- X {
- X switch(BufferMode())
- X {
- X case LITERAL:
- X if (InputMode() == COPY)
- X {
- X BytesSent += SendBuffer(Inv);
- X InitCopyMode(Fp, &NBytes, Inv);
- X }
- X else
- X {
- X ContLitMode(Fp, &NBytes, Inv);
- X }
- X break;
- X case COPY:
- X if (CurrByte == Buffer[0])
- X {
- X ContCopyMode(Fp, &NBytes, Inv);
- X }
- X else
- X {
- X BytesSent += SendBuffer(Inv);
- X if (InputMode() == COPY)
- X {
- X InitCopyMode(Fp, &NBytes, Inv);
- X }
- X else
- X {
- X InitLitMode(Fp, &NBytes, Inv);
- X }
- X }
- X break;
- X default:
- X Error("Bad Buffer Mode... Sorry\n");
- X break;
- X }
- X }
- X BytesSent += SendBuffer(Inv);
- X /* Send out rem'g 2 bytes in LITERAL mode. */
- X Buffer[0] = CurrByte;
- X Buffer[1] = NextByte;
- X BufCount = 1;
- X BytesSent += SendBuffer(Inv);
- X return(BytesSent);
- X}
- X
- X/******************************************************************************
- X* Diagnostic Routines. *
- X******************************************************************************/
- XDiagRecLRun(Rlength)
- Xint Rlength;
- X{
- X#ifdef DIAGS
- X if (Rlength > DiagMaxRunLength)
- X DiagMaxRunLength = Rlength;
- X DiagSumRunLength += Rlength;
- X DiagNumRuns++;
- X#endif
- X}
- X
- XDiags()
- X{
- X#ifdef DIAGS
- X fprintf(stderr, "Longest Run (<= 128) = %d\n", DiagMaxRunLength);
- X fprintf(stderr, "Number of Runs over 128 = %d\n", DiagNLongRuns);
- X fprintf(stderr, "Average Run Length of %d. (%d Runs)\n",
- X (int) DiagSumRunLength / DiagNumRuns, DiagNumRuns);
- X#endif
- X}
- X
- X/******************************************************************************
- X* PostScript Output Routines. *
- X******************************************************************************/
- XPrintPostScriptRoutines(ras_h, ras_w, ras_d, tx, ty, sx, sy, rot)
- Xint ras_h, ras_w, ras_d;
- Xdouble tx, ty, sx, sy, rot;
- X{
- X printf("%%!\n/inch {72 mul} def\n");
- X printf("/bpp %d def\n", ras_d);
- X printf("/scanlines %d def\n", ras_h);
- X printf("/scansize %d def\n", ras_w);
- X printf("/bitmapx\n{");
- X printf(" %d %d %d [%d 0 0 %d 0 %d] ", ras_w, ras_h, ras_d, ras_w,
- X -ras_h, ras_h);
- X printf("{currentfile readrlehexstring pop } image\n} def\n");
- X printf("gsave\n");
- X printf("%f inch %f inch translate\n",tx, ty);
- X printf("%f rotate\n", rot );
- X printf("%f inch %f inch scale\n", sx, sy);
- X printf("/readrlehexstring\t%% rle_file => decoded_string boolean\n");
- X printf("{\n\t/fileptr exch def\n\tfileptr 1 string readhexstring {");
- X printf("\n\t\t0 get dup 128 and 0 eq\n");
- X printf("\t\t{ 1 add /Buffer exch string def\n");
- X printf("\t\t\tfileptr Buffer readhexstring\n\t\t}\n\t\t{");
- X printf(" 256 exch sub /BufCount exch def\n");
- X printf("\t\t\t/Buffer BufCount 1 add string def\n");
- X printf("\t\t\t/RunInt fileptr 1 string readhexstring");
- X printf(" pop 0 get def\n");
- X printf("\t\t\t0 1 BufCount { RunInt Buffer 3 1 roll put } for\n");
- X printf("\t\t\tBuffer true\n\t\t} ifelse\n\t}\n\t{ false } ifelse\n");
- X printf("} def\n");
- X printf("/clipathx\n{\tnewpath\n\t0 0 moveto\n\t%f inch 0", sx);
- X printf(" lineto\n\t%f inch %f inch lineto\n\t0 %f inch lineto\n",
- X sx, sy, sy);
- X printf("\tclosepath\n} def\nclipathx clip\n");
- X printf("bitmapx\n");
- X}
- X
- XPrintPostScriptClosing()
- X{
- X printf("\ngrestore\n");
- X printf("showpage\n");
- X}
- X
- X/******************************************************************************
- X* Error Routine. *
- X******************************************************************************/
- XError(S1, S2, S3)
- Xchar *S1, *S2, *S3;
- X{
- X fprintf(stderr, S1, S2, S3);
- X exit(-1);
- X}
- SHAR_EOF
- if test 12873 -ne "`wc -c 'sun2ps.c'`"
- then
- echo shar: error transmitting "'sun2ps.c'" '(should have been 12873 characters)'
- fi
- echo shar: extracting "'sun2ps.l'" '(3986 characters)'
- if test -f 'sun2ps.l'
- then
- echo shar: over-writing existing file "'sun2ps.l'"
- fi
- sed 's/^X//' << \SHAR_EOF > 'sun2ps.l'
- X.TH SUN2PS L "" "" "User Contributed Software"
- X.SH NAME
- Xsun2ps \- a Sun rasterfile to PostScript image filter using run length
- Xencoding
- X.SH SYNOPSIS
- X.B sun2ps
- X[
- X.B \-s sizex sizey
- X] [
- X.B \-t transx transy
- X] [
- X.B \-r rot
- X] [
- X.B \-i
- X] [
- X.B \-a
- X] [
- X.B \-l
- X] [ rasfile ]
- X.SH OPTIONS
- X.TP
- X.B \-s
- XSet the x and y size of the image to
- X.I sizex
- Xand
- X.I sizey
- Xinches, respectively. Defaults to 7.5 x 10 inches.
- X.TP
- X.B \-t
- XTranslate the origin of the x-y axis to
- X.I transx
- Xand
- X.I transy
- Xinches, respectively. Defaults to (0.5, 0.5) inches.
- X.TP
- X.B \-r
- XRotate the image by
- X.I rot
- Xdegrees. Note: rotating the image
- X.I does not
- Xtranslate the x-y origin. When using this option, be sure to translate
- Xthe origin accordingly. Default is 0 degrees. See the -l option.
- X.TP
- X.B \-i
- XInvert the image. This implies a white image on a black background.
- XDefault is a black image on a white background.
- X.TP
- X.B \-l
- XLandscape mode. This option will override any previous size, translation
- Xand rotation settings. Its is intended to provide a quick, landscape
- Ximage. Default is off (or portrait mode).
- X.TP
- X.B \-a
- XAutomatically resize the image to conform to its aspect ratio. Normally,
- X.I sun2ps
- Xwill scale the image to the full page size (or
- X.I sizex
- Xand
- X.I sizey,
- Xif given). Default is off.
- X.SH DESCRIPTION
- X.sp 1
- X.TP
- X.B Overview
- X.br
- X.sp 1
- X.I Sun2ps
- Xtranslates images stored in Sun Rasterfile format (see
- X.I rasterfile(5)
- Xfor info on file format) to standard PostScript code. Run length
- Xencoding/decoding was also incorporated into
- X.I sun2ps
- Xto decrease the size of the text file produced (full sized screendumps
- Xproduce a file in excess of 300K, without compression). The specifics
- Xof the encoding algorithm are described below. Using this compression,
- Xfull screen dumps (using
- X.I screendump(1))
- Xcan be compressed from 20% to 30% of the original. Unfortunately,
- Xdue to the nature of the text file, binary image data is doubled
- Xsince each byte is stored as two hex digits.
- X.br
- X.TP
- X.B Run Length Encoding
- X.br
- X.sp 1
- XThe run length encoding strategy used in
- X.I sun2ps
- Xis a byte-level scheme that allows runs up to 128. A maximum run length
- Xof 128 was chosen so as to conform with images produced by the Degas Elite
- Xsystem for the Atari ST. Our intent is to allow for the display of Degas
- Ximages on NeWS windows. Using this scheme, image data is sent in two types
- Xof packets, or buffers. Along with each buffer is a count, which identifies
- Xthe size of the packet and its type. Copy packets, or "runs" in their most
- Xconventional sense, consist of a single byte with its count specifying
- Xthe number of times this byte is to be repeated. Literal packets consist of
- Xa buffer of non-repeated bytes with its count specifying the size of the
- Xpacket. A buffer count of
- X.I N
- Xindicates:
- X.br
- X.sp 1
- X.I N = 0..127
- X: Literal mode. Send out the next
- X.I N
- X+ 1 bytes as is.
- X.br
- X.I N = -1..-127
- X: Copy mode. Copy the next byte
- X.I -N
- X+ 1 times.
- X.br
- X.I N = -128
- X: Ignore.
- X.br
- X.TP
- X.B Input, Output & Stderr
- X.sp 1
- X.I Sun2ps
- Xsends its PostScript output to stdout. An input rasterfile may be specified
- Xon the command line, or if excluded, stdin is used.
- X.I Sun2ps
- Xcan be compiled with diagnostic information being reported to stderr.
- XDiagnostics include compression ratio, average run length, and number of
- Xruns over the maximum. See the Makefile for setting the appropriate
- Xflags for the diagnostic output.
- X.SH EXAMPLES
- X.br
- X.sp 1
- XStandard usage is:
- X.br
- X.na
- X.sp 1
- XMyPrompt% screendump | sun2ps -l | lpr OR
- X.br
- X.sp 1
- XMyPrompt% screendump | sun2ps -l > screen.ps OR
- X.br
- X.sp 1
- XMyPrompt% sun2ps -a /u/big/jerk/image.ras > image.ps
- X.br
- X.ad
- X.SH AUTHORS
- X.na
- XGlenn Boysko (boysko@mandrill.ces.cwru.edu)
- X ({decvax, sun}!mandrill!boysko)
- X.ad
- X.br
- X.sp 1
- XWith references to prior work ("postimage") by:
- X.na
- X.br
- X.sp 1
- XJ.R. Bammi (bammi@mandrill.ces.cwru.edu)
- X ({decvax, sun}!mandrill!bammi)
- X.ad
- X.SH SEE ALSO
- Xscreendump(1), rasterfile(5), rasfilter8to1(1).
- X.SH BUGS
- XNo Bugs! Just features!
- X.SH DATE
- X3/25/88
- SHAR_EOF
- if test 3986 -ne "`wc -c 'sun2ps.l'`"
- then
- echo shar: error transmitting "'sun2ps.l'" '(should have been 3986 characters)'
- fi
- # End of shell archive
- exit 0
-